
/* verilator lint_off UNDRIVEN */
/* verilator lint_off UNUSED */
//--xuezhen--

`include "defines.v"

module id_stage(
  //input
  //input wire clk,  //added in 0407
  input wire rst,
  input wire [31 : 0]inst_i,   //instruction from instruction memory
  input wire [`REG_BUS]pc_i,
  //from reg
  input wire [`REG_BUS]rs1_data,
  input wire [`REG_BUS]rs2_data,
  
  //output
  //to reg
  output reg rs1_r_ena,
  output wire [4 : 0]rs1_r_addr,
  output reg rs2_r_ena,
  output wire [4 : 0]rs2_r_addr,
  //pass
  output reg rd_w_ena,
  output wire [4 : 0]rd_w_addr,
  output reg l_mem,
  output reg s_mem,
  output reg [4 : 0]inst_type,
  output reg [7 : 0]alu_opcode,  //operation code to the ALU(exe module)
  output reg alu_single_word,  //enable if do 32bit arith
  output reg [`REG_BUS]op1,
  output reg [`REG_BUS]op2,
  output reg [`REG_BUS]rs1_data_o,
  output reg [`REG_BUS]rs2_data_o,
  output reg [1:0]datasize,
  output reg unsigned_load,
  output reg [2:0]branch_type,
  output wire [1:0]jump_type,   //00: not jump   10:JAL   11:JALR
  output wire [31 : 0]inst_o,
  output wire [`REG_BUS]pc_o

);

wire [31 : 0]inst;
assign inst = inst_i;   //for decode
assign inst_o = inst_i;   // for difftest
assign pc_o = pc_i;


// I-type
wire [6  : 0]opcode;
wire [4  : 0]rd;
wire [2  : 0]func3;
wire [4  : 0]rs1;
wire [11 : 0]imm_I;
assign opcode = inst[6  :  0];
assign rd     = inst[11 :  7];
assign func3  = inst[14 : 12];
assign rs1    = inst[19 : 15];
assign imm_I    = inst[31 : 20];

//R-type   //added in 04 July
wire [6:0]func7;
wire [4:0]rs2;
assign func7 = inst[31:25];
assign rs2 = inst[24:20];

//S-type  
wire [11:0]imm_S;
assign imm_S[11:5] = inst[31:25];
assign imm_S[4:0] = inst[11 :  7];

//B-type  
wire [12:0]imm_B;
assign imm_B[12] = inst[31];
assign imm_B[10:5] = inst[30:25];
assign imm_B[4:1] = inst[11:8];
assign imm_B[11] = inst[7];
assign imm_B[0] = 1'b0;

//U-type  //added in 022 July
wire [19:0]imm_U;
assign imm_U = inst[31:12];

//J-type
wire [20:0]imm_J;
assign imm_J[20] = inst[31];
assign imm_J[10:1] = inst[30:21];
assign imm_J[11] = inst[20];
assign imm_J[19:12] = inst[19:12];
assign imm_J[0] = 1'b0;



/*
assign rs1_r_ena  = ( rst == 1'b1 ) ? 0 : inst_type[4];
assign rs1_r_addr = ( rst == 1'b1 ) ? 0 : ( inst_type[4] == 1'b1 ? rs1 : 0 );
assign rs2_r_ena  = 0;  
assign rs2_r_addr = 0;

assign rd_w_ena   = ( rst == 1'b1 ) ? 0 : inst_type[4];
assign rd_w_addr  = ( rst == 1'b1 ) ? 0 : ( inst_type[4] == 1'b1 ? rd  : 0 );

assign op1 = ( rst == 1'b1 ) ? 0 : ( inst_type[4] == 1'b1 ? rs1_data : 0 );   //data to be operate
assign op2 = ( rst == 1'b1 ) ? 0 : ( inst_type[4] == 1'b1 ? { {52{imm[11]}}, imm } : 0 );   //data to be operate
*/

assign rs1_r_addr = (rs1_r_ena == 1'b1) ? rs1 : 5'b00000 ;
assign rs2_r_addr = (rs2_r_ena == 1'b1) ? rs2 : 5'b00000 ;
assign rs1_data_o = (rs1_r_ena == 1'b1) ? rs1_data : `ZERO_WORD;
assign rs2_data_o = (rs2_r_ena == 1'b1) ? rs2_data : `ZERO_WORD;
assign rd_w_addr  = (rd_w_ena == 1'b1) ? rd  : 5'b00000 ;


always @(*)
begin
  if( rst == 1'b1 )
  begin
    alu_opcode = 8'b00000000;
    alu_single_word = 1'b0;
    inst_type = 5'b00000;
    rs1_r_ena = 1'b0;
    rs2_r_ena  = 1'b0;  
    rd_w_ena  = 1'b0;
    op1 = `ZERO_WORD;   
    op2 = `ZERO_WORD; 
    l_mem = 0;
    s_mem = 0;
    datasize = 2'b00;  //00:byte 01:half word 10:word 11:double words
    unsigned_load = 1'b0;
    branch_type = 3'b000;
    jump_type = 2'b00;
  end
  else begin
    ////////DEFAULT////////
    
    alu_opcode = 8'b00000000;
    alu_single_word = 1'b0;
    inst_type = 5'b00000;
    rs1_r_ena = 1'b0;
    rs2_r_ena  = 1'b0;  
    rd_w_ena  = 1'b0;
    op1 = `ZERO_WORD;   
    op2 = `ZERO_WORD; 
    l_mem = 0;
    s_mem = 0;
    datasize = 2'b00;  //00:byte 01:half word 10:word 11:double words
    unsigned_load = 1'b0;
    branch_type = 3'b000;
    jump_type = 2'b00;
    

    casez ({func7,func3,opcode[6:0]})  //7+3+7=17bit
      ////////BUBBLE////////
      /*
      17'b???????_???_?????00 : 
      begin
        alu_opcode = 8'b00000000;
        alu_single_word = 1'b0;
        inst_type = 5'b00000;
        rs1_r_ena = 1'b0;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b0;
        op1 = `ZERO_WORD;   
        op2 = `ZERO_WORD; 
        l_mem = 0;
        s_mem = 0;
        datasize = 2'b00;
      end
      */
      //arith
      ////////ADD////////
      17'b0000000_000_0110011 : 
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data;   
      end 
      ////////ADDI////////
      17'b???????_000_0010011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SUB////////
      17'b0100000_000_0110011 :  
      begin
        alu_opcode = `ALU_SUB;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data;   
      end 
      ///////LUI////////
      17'b???????_???_0110111 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b0;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = `ZERO_WORD;   
        op2 = {{32{imm_U[19]}},imm_U,{12{1'b0}}};   //is this correct?
      end 
      ///////AUIPC////////
      17'b???????_???_0010111 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b0;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = pc_i;   
        op2 = {{32{imm_U[19]}},imm_U,{12{1'b0}}};   //is this correct?
      end
      ///////ADDW////////
      17'b0000000_000_0111011 :  
      begin
        alu_opcode = `ALU_ADD;
        alu_single_word = 1'b1;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data; 
      end
      ////////ADDIW////////
      17'b???????_000_0011011 :  
      begin
        alu_opcode = `ALU_ADD;
        alu_single_word = 1'b1;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SUBW////////
      17'b0100000_000_0111011 :  
      begin
        alu_opcode = `ALU_SUB;
        alu_single_word = 1'b1;
        inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data;   
      end 

      //logic
      ///////XOR////////
      17'b0000000_100_0110011 :  
      begin
        alu_opcode = `ALU_XOR;
        inst_type = 5'b01000;  //logic
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data;   
      end
      ///////XORI////////
      17'b???????_100_0010011 :  
      begin
        alu_opcode = `ALU_XOR;
        inst_type = 5'b01000;  //logic
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end
      ///////OR////////
      17'b0000000_110_0110011 :  
      begin
        alu_opcode = `ALU_OR;
        inst_type = 5'b01000;  //logic
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data;   
      end
      ///////ORI////////
      17'b???????_110_0010011 :  
      begin
        alu_opcode = `ALU_OR;
        inst_type = 5'b01000;  //logic
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end  
      ///////AND////////
      17'b0000000_111_0110011 :  
      begin
        alu_opcode = `ALU_AND;
        inst_type = 5'b01000;  //logic
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data;   
      end
      ///////ANDI////////
      17'b???????_111_0010011 :  
      begin
        alu_opcode = `ALU_AND;
        inst_type = 5'b01000;  //logic
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end   
      
      //compare
      ///////SLT////////
      17'b0000000_010_0110011 :  
      begin
        alu_opcode = `ALU_SLT;
        //inst_type = 5'b01000;  //what is the inst_type for compare?
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data; 
      end  
      ///////SLTI////////
      17'b???????_010_0010011 :  
      begin
        alu_opcode = `ALU_SLT;
        //inst_type = 5'b01000;  
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end
      ///////SLTU////////
      17'b0000000_011_0110011 :  
      begin
        alu_opcode = `ALU_SLTU;
        //inst_type = 5'b01000;  
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = rs2_data; 
      end  
      ///////SLTIU////////
      17'b???????_011_0010011 :  
      begin
        alu_opcode = `ALU_SLTU;
        //inst_type = 5'b01000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end

      ///////LB////////
      17'b???????_000_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b00;
        unsigned_load = 1'b0;
      end
      ///////LH////////
      17'b???????_001_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b01;
        //unsigned_load = 1'b0;
      end
      ///////LBU////////
      17'b???????_100_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b00;
        unsigned_load = 1'b1;
      end
      ///////LHU////////
      17'b???????_101_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b01;
        unsigned_load = 1'b1;
      end
      ///////LW////////
      17'b???????_010_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b10;
        //unsigned_load = 1'b0;
      end
      ///////LWU////////
      17'b???????_110_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b10;
        unsigned_load = 1'b1;
      end
      ///////LD////////
      17'b???????_011_0000011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };
        l_mem = 1;
        s_mem = 0;
        datasize = 2'b11;
        //unsigned_load = 1'b0;
      end
      ///////SB////////
      17'b???????_000_0100011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = rs1_data;   
        op2 = { {52{imm_S[11]}}, imm_S };
        l_mem = 0;
        s_mem = 1;
        datasize = 2'b00;
      end
      ///////SH////////
      17'b???????_001_0100011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = rs1_data;   
        op2 = { {52{imm_S[11]}}, imm_S };
        l_mem = 0;
        s_mem = 1;
        datasize = 2'b01;
      end
      ///////Sw////////
      17'b???????_010_0100011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = rs1_data;   
        op2 = { {52{imm_S[11]}}, imm_S };
        l_mem = 0;
        s_mem = 1;
        datasize = 2'b10;
      end
      ///////SD////////
      17'b???????_011_0100011 :  
      begin
        alu_opcode = `ALU_ADD;
        inst_type = 5'b00100;  // load-store
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = rs1_data;   
        op2 = { {52{imm_S[11]}}, imm_S };
        l_mem = 0;
        s_mem = 1;
        datasize = 2'b11;
      end

      //shift
      ////////SLL////////
      17'b0000000_001_0110011 : 
      begin
        alu_opcode = `ALU_SLL;
        //alu_single_word = 1'b0;
        //inst_type = 5'b10000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {58{1'b0}}, rs2_data[5:0] };   
      end 
      ////////SLLI////////
      17'b000000?_001_0010011 :  
      begin
        alu_opcode = `ALU_SLL;
        //alu_single_word = 1'b0;
        //inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SLLW////////
      17'b0000000_001_0111011 : 
      begin
        alu_opcode = `ALU_SLL;
        alu_single_word = 1'b1;
        //inst_type = 5'b10000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {59{1'b0}}, rs2_data[4:0] };   
      end 
      ////////SLLIW////////
      17'b0000000_001_0011011 :  
      begin
        alu_opcode = `ALU_SLL;
        alu_single_word = 1'b1;
        //inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SRL////////
      17'b0000000_101_0110011 : 
      begin
        alu_opcode = `ALU_SRL;
        //alu_single_word = 1'b0;
        //inst_type = 5'b10000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {58{1'b0}}, rs2_data[5:0] };   
      end 
      ////////SRLI////////
      17'b000000?_101_0010011 :  
      begin
        alu_opcode = `ALU_SRL;
        //alu_single_word = 1'b0;
        //inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SRLW////////
      17'b0000000_101_0111011 : 
      begin
        alu_opcode = `ALU_SRL;
        alu_single_word = 1'b1;
        //inst_type = 5'b10000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = {{32{1'b0}},rs1_data[31:0]};   //set zero to the top 32 bits,equal to single word right shift
        op2 = { {59{1'b0}}, rs2_data[4:0] };   
      end 
      ////////SRLIW////////
      17'b0000000_101_0011011 :  
      begin
        alu_opcode = `ALU_SRL;
        alu_single_word = 1'b1;
        //inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = {{32{1'b0}},rs1_data[31:0]};   //set zero to the top 32 bits,equal to single word right shift
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SRA////////
      17'b0100000_101_0110011 : 
      begin
        alu_opcode = `ALU_SRA;
        //alu_single_word = 1'b0;
        //inst_type = 5'b10000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {58{1'b0}}, rs2_data[5:0] };   
      end 
      ////////SRAI////////
      17'b010000?_101_0010011 :  
      begin
        alu_opcode = `ALU_SRA;
        //alu_single_word = 1'b0;
        //inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 
      ////////SRAW////////
      17'b0100000_101_0111011 : 
      begin
        alu_opcode = `ALU_SRA;
        alu_single_word = 1'b1;
        //inst_type = 5'b10000; 
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b1;
        op1 = {{32{rs1_data[31]}},rs1_data[31:0]};   //set sign to the top 32 bits, equal to single word right shift
        op2 = { {59{1'b0}}, rs2_data[4:0] };   
      end 
      ////////SRAIW////////
      17'b0100000_101_0011011 :  
      begin
        alu_opcode = `ALU_SRA;
        alu_single_word = 1'b1;
        //inst_type = 5'b10000;  //arith
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = {{32{rs1_data[31]}},rs1_data[31:0]};   //set sign to the top 32 bits, equal to single word right shift
        op2 = { {52{imm_I[11]}}, imm_I };   
      end 

      ////////BEQ////////
      17'b???????_000_1100011 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        //inst_type = 5'b00000;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = pc_i;   
        op2 = { {51{imm_B[12]}}, imm_B }; 
        branch_type = `B_EQ;
        jump_type = 2'b00;
      end
      ////////BNE////////
      17'b???????_001_1100011 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        //inst_type = 5'b00000;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = pc_i;   
        op2 = { {51{imm_B[12]}}, imm_B }; 
        branch_type = `B_NE;
        jump_type = 2'b00;
      end
      ////////BLT////////
      17'b???????_100_1100011 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        //inst_type = 5'b00000;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = pc_i;   
        op2 = { {51{imm_B[12]}}, imm_B }; 
        branch_type = `B_LT;
        jump_type = 2'b00;
      end
      ////////BGE////////
      17'b???????_101_1100011 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        //inst_type = 5'b00000;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = pc_i;   
        op2 = { {51{imm_B[12]}}, imm_B }; 
        branch_type = `B_GE;
        jump_type = 2'b00;
      end
      ////////BLTU////////
      17'b???????_110_1100011 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        //inst_type = 5'b00000;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = pc_i;   
        op2 = { {51{imm_B[12]}}, imm_B }; 
        branch_type = `B_LTU;
        jump_type = 2'b00;
      end
      ////////BGEU////////
      17'b???????_111_1100011 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        //inst_type = 5'b00000;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b1;  
        rd_w_ena  = 1'b0;
        op1 = pc_i;   
        op2 = { {51{imm_B[12]}}, imm_B }; 
        branch_type = `B_GEU;
        jump_type = 2'b00;
      end


      ////////JAL////////
      17'b???????_???_1101111 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        inst_type = 5'b00010;
        rs1_r_ena = 1'b0;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = pc_i;   
        op2 = { {43{imm_J[20]}}, imm_J }; 
        branch_type = 3'b000;
        jump_type = 2'b10;
      end
      ////////JALR////////
      17'b???????_000_1100111 :  
      begin
        alu_opcode = `ALU_ADD;
        //alu_single_word = 1'b0;
        inst_type = 5'b00010;
        rs1_r_ena = 1'b1;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b1;
        op1 = rs1_data;   
        op2 = { {52{imm_I[11]}}, imm_I }; 
        branch_type = 3'b000;
        jump_type = 2'b11;
      end




      ////////DEFAULT////////
      default :
      begin
        alu_opcode = 8'b00000000;
        alu_single_word = 1'b0;
        inst_type = 5'b00000;
        rs1_r_ena = 1'b0;
        rs2_r_ena  = 1'b0;  
        rd_w_ena  = 1'b0;
        op1 = `ZERO_WORD;   
        op2 = `ZERO_WORD; 
        l_mem = 0;
        s_mem = 0;
        datasize = 2'b00;  //00:byte 01:half word 10:word 11:double words
        unsigned_load = 1'b0;
        branch_type = 3'b000;
        jump_type = 2'b00;
      end
    endcase
  end

end

/*
wire inst_addi =   ~opcode[2] & ~opcode[3] & opcode[4] & ~opcode[5] & ~opcode[5]   //where is opecode[6]
                 & ~func3[0] & ~func3[1] & ~func3[2];             

// arith inst: 10000; logic: 01000;
// load-store: 00100; j: 00010;  sys: 00001           
assign inst_type[4] = ( rst == 1'b1 ) ? 0 : inst_addi;

assign inst_opcode[0] = (  rst == 1'b1 ) ? 0 : inst_addi;
assign inst_opcode[1] = (  rst == 1'b1 ) ? 0 : 0;
assign inst_opcode[2] = (  rst == 1'b1 ) ? 0 : 0;
assign inst_opcode[3] = (  rst == 1'b1 ) ? 0 : 0;
assign inst_opcode[4] = (  rst == 1'b1 ) ? 0 : inst_addi;
assign inst_opcode[5] = (  rst == 1'b1 ) ? 0 : 0;
assign inst_opcode[6] = (  rst == 1'b1 ) ? 0 : 0;
assign inst_opcode[7] = (  rst == 1'b1 ) ? 0 : 0;
*/





endmodule
